home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
System Booster
/
System Booster.iso
/
Archives
/
ForCLI
/
CutAndPaste.lha
/
CutAndPaste
/
paste.c
< prev
next >
Wrap
C/C++ Source or Header
|
1987-09-01
|
5KB
|
243 lines
/*
* A version of paste. This is compatable with AT&T paste command SVR2.
*
* John Weald
*
*/
#include <stdio.h>
#define MAXLINE 1024 /* Max. allowed line length */
#define MAXFILES 12 /* Max. number of input files */
extern void exit();
main(argc, argv)
int argc;
char *argv[];
{
extern int optind;
extern char *optarg;
int c; /* For getopt() */
char conchars[MAXFILES]; /* The concatination characters */
int nconchars = 1; /* The number of conchars[] */
int serial = 0; /* True if old type paste "-s" */
conchars[0] = '\t';
while ((c = getopt(argc, argv, "sd:")) != EOF)
{
switch(c)
{
case 's':
/* Concatinate the same file serially */
serial++;
break;
case 'd':
/* Use other than a single tab */
nconchars = setconcat(conchars, optarg);
break;
default:
/* Does not return */
prusage();
}
}
if (serial)
spaste(&argv[optind], conchars, nconchars);
else
paste(&argv[optind], conchars, nconchars);
exit(0);
/* NOTREACHED */
}
/*
* paste()
*
* Do the actual paste.
*/
paste(files, con, ncons)
char *files[]; /* Null terminated list of input files */
char con[]; /* The concatination characters */
char ncons; /* The number of above */
{
char ibuf[MAXLINE+1]; /* The input buffer */
char obuf[MAXLINE]; /* The output buffer */
register char *iptr = ibuf;
register char *optr = obuf;
FILE *fps[MAXFILES]; /* One for each open file */
int f; /* Number of files opened */
int allfiles; /* Ditto */
int inc; /* True if concat. char. == '\0'*/
int ocount; /* Output buffer char. count */
char c; /* The current concat. char */
int i;
/*
* Open all the input files, any filename of '-' means
* the standard input. No file name means standard input.
*/
for (f = 0; files[f] != (char *)NULL; f++)
{
if (*files[f] == '-')
fps[f] = stdin;
else if ((fps[f] = fopen(files[f], "r")) == (FILE *)NULL)
{
fprintf(stderr, "Failed to open file %s\n", files[f]);
exit(1);
}
if (f >= MAXFILES)
{
fprintf(stderr,
"Too many files. Maximum allowed is %d\n", MAXFILES);
exit(1);
}
}
if (files[0] == (char *)NULL)
{
fps[0] = stdin;
f++;
}
/*
* Read all lines until no more lines in any file.
*/
allfiles = f;
while (f)
{
optr = obuf;
ocount = 0;
/*
* Join lines from all files.
*
* The concatination character may be '\0' which
* means no character. The variable inc is an indication
* of the concatination character being '\0', we need to
* if there is a concatination character to move up the
* output buffer.
*
* The concatination characters are used in a round robin
* list.
*/
for (inc = 0, i = 0; i < allfiles; i++)
{
iptr = ibuf;
optr += inc;
/* To save repeated evaluation */
c = con[i % ncons];
inc = c == '\0' ? 0 : 1;
if (fps[i] == (FILE *)NULL)
{
/* No more lines in this file. */
*optr = c;
continue;
}
if (fgets(ibuf, sizeof(ibuf), fps[i]) == (char *)NULL)
{
/* Reached EOF - finished with the file */
(void)fclose(fps[i]);
fps[i] = (FILE *)NULL;
*optr = c;
f--;
continue;
}
/*
* Replace the newline with the concatination character.
* There is no need to look for end-of-string since
* we know that
* a) if ibuf is full to the max, then we will
* overflow obuf before we hit the end of ibuf.
* b) if ibuf is not full, then it must contain a
* a newline character, but may or may not
* fit into obuf.
*/
for (; *iptr != '\n'; ocount++)
{
/* Need space for trailing null */
if (ocount >= sizeof(obuf) - 1)
{
fprintf(stderr, "Output line too long, maximum length is %d.\n", MAXLINE);
exit(1);
}
*optr++ = *iptr++;
}
*optr = c;
}
if (f)
{
*optr = '\0';
puts(obuf);
}
}
}
/*
* setconcat()
*
* Parse the concatination characters and place them in the array c.
* Return the number of concatination characters.
*
* Specials are:
* \n - Newline
* \t - Tab (default)
* \ - Backslash
* \0 - No concatination character
*/
static int
setconcat(c, in)
char *c;
char *in;
{
int i; /* The number seen so far */
for (i = 0; *in != '\0'; in++, c++, i++)
{
if (i > MAXFILES)
{
fprintf(stderr, "Too many concatination characters, maximum allowed is %d\n", MAXFILES);
exit(1);
}
if (*in != '\\')
{
*c = *in;
continue;
}
in++;
switch (*in)
{
case 'n':
*c = '\n';
break;
case 't':
*c = '\t';
break;
case '0':
*c = '\0';
break;
default:
/* Includes '\\' */
*c = *in;
break;
}
}
return(i);
}
static
prusage()
{
fprintf(stderr, "USAGE: paste [-s] [-d<list>] files\n");
exit(1);
}